#pragma once
#include <iostream>
#include <sys/epoll.h>
#include "Log.hpp"
#include "Comm.hpp"
using namespace LogModule;

class Epoller
{
    const static int _revs_num = 64;

public:
    Epoller()
    {
    }
    void Init()
    {
        _epfd = epoll_create(256);
        if (_epfd < 0)
        {
            LOG(LogLevel::ERROR) << "epoll_create error";
            exit(EPOLL_CREATE_ERR);
        }
    }

    void Add(int fd, uint32_t events)
    {
        Ctrl(fd, events, EPOLL_CTL_ADD);
    }
    void Mod(int fd, uint32_t events)
    {
        Ctrl(fd, events, EPOLL_CTL_MOD);
    }
    void Del(int fd)
    {
        int ret = epoll_ctl(_epfd,EPOLL_CTL_DEL,fd,nullptr);
        if(ret<0)
            LOG(LogLevel::ERROR) << "epoll_ctl error";
    }
    int Wait(struct epoll_event revs[], int revs_num)
    {
        int n = epoll_wait(_epfd, revs, revs_num, -1);
        if (n < 0)
        {
            LOG(LogLevel::ERROR) << "epoll_wait error";
        }
        else if (n == 0)
        {
            LOG(LogLevel::DEBUG) << "time out....";
        }
        return n;
    }

    ~Epoller()
    {
    }

private:
    void Ctrl(int fd, uint32_t events, int op)
    {
        struct epoll_event ev;
        ev.data.fd = fd;
        ev.events = events;
        int ret = epoll_ctl(_epfd, op, fd, &ev);
        if (ret < 0)
        {
            LOG(LogLevel::ERROR) << "epoll_ctl error";
        }
    }

private:
    int _epfd;
    struct epoll_event _revs[_revs_num];
};